/* ----------------------------------------------------------------------------------------------------------------
 * Entity
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.entity 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import pure.debug.Logger;
	import pure.engine.renderer.Renderer;
	import pure.engine.core.RenderableCore;

	import pure.engine.status.IStatus;
	import pure.engine.system.ProcessManager;
	import flash.events.IEventDispatcher;
	import pure.engine.core.IRenderable;
	import pure.engine.world.WorldContent;
	import pure.engine.system.ns_despair;
	
	use namespace ns_despair;
	
	
	
	/// @eventType	pure.engine.events.EntityMouseEvent.CLICK
	[Event(name="click", type="pure.engine.events.EntityMouseEvent")] 

	/// @eventType	pure.engine.events.EntityMouseEvent.MOUSE_DOWN
	[Event(name="mouseDown", type="pure.engine.events.EntityMouseEvent")] 

	/// @eventType	pure.engine.events.EntityMouseEvent.MOUSE_UP
	[Event(name="mouseUp", type="pure.engine.events.EntityMouseEvent")] 

	/// @eventType	pure.engine.events.EntityMouseEvent.MOUSE_MOVE
	[Event(name="mouseMove", type="pure.engine.events.EntityMouseEvent")] 

	/// @eventType	pure.engine.events.EntityMouseEvent.MOUSE_OUT
	[Event(name="mouseOut", type="pure.engine.events.EntityMouseEvent")] 

	/// @eventType	pure.engine.events.EntityMouseEvent.MOUSE_OVER
	[Event(name = "mouseOver", type = "pure.engine.events.EntityMouseEvent")] 
	
	
	/**
	 * 实体
	 * [Author] - PURE
	 * 
	 * [Process] - ① Tick更新动画
	 *             ② Frame更新画像缓存
	 * 
	 */
public class Entity extends RenderableCore implements IRenderable
{        


	
	

	//======================
	// Property
	//====================== 
		
	
	// 名字
	public function get name():String { return m_name; }
	
	// ID
	public function get id():int { return m_id; }
	
	// 当前所在世界
	public function get worldContent():WorldContent { return m_worldContent; }

	// 坐标X
	public function get x():Number { return m_x; }
	public function set x(v:Number):void { m_x = v; }
	
	// 坐标Y
	public function get y():Number { return m_y; }
	public function set y(v:Number):void { m_y = v; }
	
	
	// 是否可见
	override public function set visible(b:Boolean):void
	{ 
		if (m_visible != b)
		{
			m_visible = b;
		}
	}
	

	
	
	// 弧度
	// ---------------------------------------------------------------------------
	// [Hint] - 实体的弧度体现了实体本身的朝向，并非某个渲染器的朝向.
	//          该属性的意义体现在缓存实体的弧度值，当它改变时会发送一个变化事件.
	//          该属性并不与渲染相关联，完全的抽象属性.
	override public function set angle(v:Number):void 
	{ 
		if (m_angle != v)
		{
			m_angle = v// < 0 ? v + TWO_PI : v;
			//m_eventDispatcher.dispatchEvent(
		}
	}
	
	// 真实区域
	public function get realRect():Rectangle
	{
		m_realRect.x = _realX + m_x;
		m_realRect.y = _realY + m_y;
		return m_realRect;
	}

	
	// 世界区域
	public function get worldRect():Rectangle
	{
		_worldRect.x = m_x - m_range;
		_worldRect.y = m_y - m_range;
		return _worldRect; 
	}

	
	
	
	
	//======================
	// Base
	//======================
	
	
	// 移动
	public function move(wx:Number, wy:Number):void
	{
		if (m_x != wx)    m_x  =  wx;
		if (m_y != wy)    m_y  =  wy;
	}

	
	// 真实体积
	public function setRealRect(rect:Rectangle):void
	{
		m_realRect = rect;
		_realX = rect.x;
		_realY = rect.y;
	}

	
	// 杀死
	// [Hint] - 实体visible立即变为false，60帧后自动移除
	public function kill():void
	{
		if (!m_alive)  return;
		
		destroy();
		
		EntityManager.unregister(this);

		clearAllStatus();
		
		m_range  =  m_x  =  m_y  =  0;
		m_rangeDirty  =  mirrorExisted  =  m_alive  =  m_visible  =  false;
	}
	

	
	

	
	
	//======================
	// Status !! (待完善)
	//======================
	
	
	public function addStatus(S:IStatus, name:String = 'S'):void
	{
		if (name == null || name == '')
		{
			throw new Error('Entity - ＃addStatus - 状态名称不可为null');
		}
		
		S.entity           =  this;
		S.absorb();
		m_statusMap[name]  =  S;
		_cachedStatusName  =  name;
	}
	
	
	public function removeStatus(name:String):void 
	{
		var S:IStatus;
		
		S = m_statusMap[name];
		S.exit();
		delete m_statusMap[name];
	}

	
	public function getStatus(name:String = null):IStatus
	{
		if (name == null || name == '')
		{
			return m_statusMap[_cachedStatusName];
		}
		return m_statusMap[name];
	}
	
	
	public function clearAllStatus():void
	{
		for (var n:String in m_statusMap)
		{
			removeStatus(n);
		}
	}


	
	
	
	//======================
	// Event Dispatcher
	//======================

	
	// 发送
	public function dispatchEvent (event:Event) : Boolean
	{
		return m_eventDispatcher.dispatchEvent(event);
	}
	
	
	// 侦听
	public function addEventListener (type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false) : void
	{
		m_eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
	}
	
	
	// 移除
	public function removeEventListener (type:String, listener:Function, useCapture:Boolean = false) : void
	{
		m_eventDispatcher.removeEventListener(type, listener, useCapture);
	}
	
	
	// 查找
	public function hasEventListener (type:String) : Boolean
	{
		return m_eventDispatcher.hasEventListener(type);
	}
	
	
	// 根查找
	public function willTrigger (type:String) : Boolean
	{
		return m_eventDispatcher.willTrigger(type);
	}
	
	
	

	
	
	/* ----------------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------------
	 */
	
	 
	 
	 
	
	// 加入渲染器
	override ns_despair function _addRenderer(R:Renderer, name:String):void
	{
		super._addRenderer(R, name);
		m_fragmentDirtyList[m_numRenderer] =  m_fragmentDirtyList[m_numRenderer - 1] = 0;
	}
		
	 
	// 更新渲染器
	
	// [-1]不可见， [0]画像不变，[1]画像变化，[2]范围变化
	override ns_despair function updateRenderer():void
	{	
		var R:Renderer;
		var i:int, flag:int;
		var newRange:Number;
		
		// 碎片状态还原
		m_fragmentDirtyList[m_numRenderer] = 0;
		for (i = 0; i < m_numRenderer; i++) 
		{
			R     =  m_rendererList[i];
			flag  =  R.m_dirtyFlag;
			
			// 变为不可见
			if(flag == -1)
			{
				m_fragmentDirtyList[i] = flag;
				m_fragmentDirtyList[m_numRenderer] = i + 1;
				R.m_dirtyFlag = 0;
				return;
			}
			
			// 更新渲染器
			else if(R.m_visible)
			{	
				R.advance();
			}
			
			// 未变化
			if(flag == 0)  continue;
			
			// 碎片变化
			m_fragmentDirtyList[i] = flag;
			m_fragmentDirtyList[m_numRenderer] = i + 1;
			R.m_dirtyFlag = 0;
			
			if (flag == 2)  
			{
				m_rangeDirty = true;
			}
		}
		
		// 面积变化
		if(m_rangeDirty)
		{
			cachedArray.length = 0;
			for (i = 0; i < m_numRenderer; i++)
			{
				R = m_rendererList[i];
				if(R.m_visible)
				{
					cachedArray.push(R.m_oldRange);
				}
			}
			cachedArray.sort(Array.NUMERIC | Array.DESCENDING);
			
			newRange = cachedArray[0];
			if (newRange != m_range)
			{
				m_range            =  newRange;
				_worldRect.width   =  newRange * 2;
				_worldRect.height  =  newRange * 2;
			}
			m_rangeDirty = false;
		}
	}
	

	
	
	
	
	
	//======================
	// Member
	//======================


	ns_despair var m_layer:int;
	
	ns_despair var m_worldContent:WorldContent;

	ns_despair var m_fragmentDirtyList:Vector.<uint> = new Vector.<uint>();  // 碎片变化列表，尾项0表示未变化.

	ns_despair var m_statusMap:Object = {};

	ns_despair var m_alive:Boolean;  // 是否活着

	ns_despair var m_eventDispatcher:EventDispatcher = new EventDispatcher();
	


	//======================
	// Cached Object
	//======================

	ns_despair var _worldRect:Rectangle = new Rectangle();

	ns_despair var m_rangeDirty:Boolean;  // 面积变化
	
	ns_despair var _cachedStatusName:String;

	ns_despair var mirrorExisted:Boolean;    // 残像是否已存在于监控器

	ns_despair var _realX:Number, _realY:Number;
	
	ns_despair static var cachedArray:Array = [];
	
	
	
	
	

}
}

